﻿namespace WizardEngine.Core
{
    using System;

    /// <summary>
    /// Wizard engine main object. 
    /// </summary>
    /// <typeparam name="T">Specific custom flow state type. Must match with flow state instance type being loaded. </typeparam>
    public interface IWizard<T> where T : FlowState, new()
    {
        /// <summary>
        /// Advances the flow to the next step updating the flow state. 
        /// </summary>
        /// <remarks>
        /// If the current step was visited out of order it will reset flow instance identifier 
        /// to the state it had when visiting it previous time. 
        /// </remarks>
        /// <param name="flowInstanceId">Flow state instance identifier. </param>
        /// <param name="update">Piece of code updating the state</param>
        void Advance(Guid flowInstanceId, FlowStateUpdate<T> update);

        /// <summary>
        /// Goes one step back in the flow. 
        /// </summary>
        /// <param name="flowInstanceId">Flow state instance identifier. </param>
        void Back(Guid flowInstanceId);

        /// <summary>
        /// Checks whether one may advance to the target step out of order. 
        /// </summary>
        /// <remarks>
        /// Only steps already visited can be navigated this way. 
        /// </remarks>
        /// <param name="flowInstanceId">Flow state instance identifier. </param>
        /// <param name="step">Target step to enter. </param>
        /// <returns>True if target step can be accessed, false otherwise. </returns>
        bool TryEnter(Guid flowInstanceId, Step step);

        /// <summary>
        /// Provides information about the current step for the flow instance. 
        /// </summary>
        /// <param name="flowInstanceId">Flow state instance identifier. </param>
        Step GetCurrentStep(Guid flowInstanceId);

        /// <summary>
        /// Discards wizard flow
        /// </summary>
        /// <param name="flowInstanceId">Flow state instance identifier. </param>
        void Discard(Guid flowInstanceId);
    }
}
